<script lang="ts">
    import { Modal } from "@skeletonlabs/skeleton-svelte";
    import { save as dialog_save } from "@tauri-apps/plugin-dialog";
    import { writeFile } from "@tauri-apps/plugin-fs";
    import { getViewportForBounds, useSvelteFlow } from "@xyflow/svelte";
    import { toPng } from "html-to-image";
    import { FolderOpen, X } from "lucide-svelte";

    interface ModalProps {
        onClose: () => void;
    }

    let props: ModalProps = $props();
    let filePath = $state("");
    let inExport = $state(false);

    const { getNodes, getNodesBounds } = useSvelteFlow();

    async function choiceFile() {
        const res = await dialog_save({
            title: "选择图片",
            filters: [
                {
                    name: "图片",
                    extensions: ["png"],
                },
            ],
        });
        if (Array.isArray(res)) {
            return;
        } else if (res == null) {
            return;
        }
        filePath = res;
    }

    async function runExport() {
        try {
            inExport = true;
            const nodesBounds = getNodesBounds(getNodes());
            const imageWidth = nodesBounds.width + 20;
            const imageHeight = nodesBounds.height + 20;
            const transform = getViewportForBounds(
                nodesBounds,
                imageWidth,
                imageHeight,
                0.1,
                10,
                "10px",
            );

            const data = await toPng(
                document.querySelector(".svelte-flow__viewport") as HTMLElement,
                {
                    filter: (node) =>
                        !node?.classList?.contains("svelte-flow__panel"),
                    backgroundColor: "#eee",
                    width: imageWidth,
                    height: imageHeight,
                    style: {
                        transform: `translate(${transform.x}px, ${transform.y}px) scale(${transform.zoom})`,
                    },
                },
            );
            const pos = data.indexOf(",");
            if (pos == -1) {
                return;
            }
            const imageDataStr = atob(data.substring(pos + 1));
            const imageData = [];
            for (let i = 0; i < imageDataStr.length; i++) {
                imageData.push(imageDataStr.charCodeAt(i));
            }
            await writeFile(filePath, Uint8Array.from(imageData));
            props.onClose();
        } catch (e) {
            console.log(e);
        } finally {
            inExport = false;
        }
    }
</script>

<Modal
    open={true}
    triggerBase="btn preset-tonal"
    contentBase="card bg-surface-200-800 p-4 space-y-4 shadow-xl shadow-surface-500 w-[600px]"
    backdropBase="backdrop-none"
    closeOnEscape={false}
    closeOnInteractOutside={false}
    onOpenChange={(ev) => {
        if (!ev.open) {
            props.onClose();
        }
    }}
>
    {#snippet content()}
        <header class="flex justify-between">
            <h4 class="h4">导出图片</h4>
            <button
                type="button"
                class="btn preset-ghost-primary-500"
                onclick={() => props.onClose()}
            >
                <X />
            </button>
        </header>

        <main>
            <div class="flex gap-2 items-center">
                <input
                    class="input flex-1 rounded-none bg-surface-100-900 text-surface-900-100 mb-2"
                    type="text"
                    bind:value={filePath}
                />
                <button
                    type="button"
                    title="选择文件"
                    onclick={() => choiceFile()}><FolderOpen /></button
                >
            </div>
            {#if inExport}
                <div>导出中......</div>
            {/if}
        </main>

        <footer class="flex justify-end gap-4">
            <button
                type="button"
                class="btn preset-tonal"
                onclick={() => props.onClose()}>取消</button
            >
            <button
                type="button"
                class="btn preset-filled-primary-900-100"
                disabled={filePath == ""}
                onclick={() => {
                    runExport();
                }}
            >
                导出
            </button>
        </footer>
    {/snippet}
</Modal>
